package com.analog.mserver.service.upload;

import java.io.IOException;
import java.io.InputStream;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.Optional;
import java.util.UUID;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import org.xmlpull.v1.XmlPullParserException;

import com.alibaba.fastjson.JSON;
import com.analog.mserver.domain.file.QueueMinioEntity;
import com.analog.mserver.domain.file.VideoEntity;
import com.analog.mserver.repository.file.VideoRepository;
import com.analog.mserver.service.base.BaseService;
import com.analog.mserver.vo.file.VideoVO;

import io.minio.MinioClient;
import io.minio.Result;
import io.minio.errors.ErrorResponseException;
import io.minio.errors.InsufficientDataException;
import io.minio.errors.InternalException;
import io.minio.errors.InvalidArgumentException;
import io.minio.errors.InvalidBucketNameException;
import io.minio.errors.InvalidEndpointException;
import io.minio.errors.InvalidPortException;
import io.minio.errors.NoResponseException;
import io.minio.errors.RegionConflictException;
import io.minio.messages.Item;

@Service("uploadService")
public class UploadService extends BaseService {
	private Logger logger = LoggerFactory.getLogger(this.getClass());

	private String videoFolder = "video";

	@Autowired
	private AmqpTemplate template;
	@Autowired
	private QueueMinioEntity queueMinioEntity;

	@Autowired
	private VideoRepository videoRepository;

	/**
	 * 上传文件
	 * @param file
	 * @return
	 */
	public boolean uploadVideo(MultipartFile file) {
		try {
			String fileName = file.getOriginalFilename();
			InputStream is = file.getInputStream();
			String contentType = file.getContentType();
			String uuid = UUID.randomUUID().toString();

			uploadFile(is, contentType, uuid);

			logger.info("上传成功 : {}; uuid : {}", file.getOriginalFilename(), uuid);
			// 保存文件信息到数据库中。
			VideoEntity po = new VideoEntity();

			po.setName(fileName);
			po.setType(contentType);
			po.setSize(file.getSize());
			po.setUuid(uuid);
			po.setFolder(videoFolder);

			videoRepository.save(po);
			// mq 通知上传完成
			queueMinioEntity.setData(po);
			template.convertAndSend("uploadvideo", JSON.toJSONString(queueMinioEntity));
		} catch (Exception e) {
			logger.error(e.getMessage(), e);
			return false;
		}

		return true;
	}

	public Page<VideoEntity> findVideoPage(VideoVO vo) {
		return videoRepository.findAll(buildPageRequest(vo.getPage(), vo.getLimit()));
	}

	/**
	 * 删除文件
	 * @param ids
	 * @return
	 */
	public Object videoDel(String[] ids) {
		MinioClient minioClient;
		try {
			minioClient = new MinioClient(queueMinioEntity.getUrl(), queueMinioEntity.getAccessKey(),
					queueMinioEntity.getAecretKey());
			//一个一个文件删除
			for (String id : ids) {
				Optional<VideoEntity> po = videoRepository.findById(Integer.parseInt(id));
				if (po.isPresent()) {
					VideoEntity ve = po.get();
					minioClient.removeObject(ve.getFolder(), ve.getUuid());
					//删除对应的切片文件
					//判断桶是否存在。如果才删除内容
					if(minioClient.bucketExists(ve.getUuid())) {
						Iterable<Result<Item>> myObjects = minioClient.listObjects(ve.getUuid());
						for (Result<Item> result : myObjects) {
							Item item = result.get();
							minioClient.removeObject(ve.getUuid(), item.objectName());
						}
						minioClient.removeBucket(ve.getUuid());
					}
					videoRepository.delete(ve);
				}
			}
		} catch (Exception e) {
 			e.printStackTrace();
		}
		return true;
	}

	/**
	 * 上传文件minio
	 * @param is
	 * @param contentType
	 * @param uuid
	 * @throws InvalidEndpointException
	 * @throws InvalidPortException
	 * @throws InvalidBucketNameException
	 * @throws NoSuchAlgorithmException
	 * @throws InsufficientDataException
	 * @throws IOException
	 * @throws InvalidKeyException
	 * @throws NoResponseException
	 * @throws XmlPullParserException
	 * @throws ErrorResponseException
	 * @throws InternalException
	 * @throws RegionConflictException
	 * @throws InvalidArgumentException
	 */
	private void uploadFile(InputStream is, String contentType, String uuid)
			throws InvalidEndpointException, InvalidPortException, InvalidBucketNameException, NoSuchAlgorithmException,
			InsufficientDataException, IOException, InvalidKeyException, NoResponseException, XmlPullParserException,
			ErrorResponseException, InternalException, RegionConflictException, InvalidArgumentException {
		MinioClient minioClient = new MinioClient(queueMinioEntity.getUrl(), queueMinioEntity.getAccessKey(),
				queueMinioEntity.getAecretKey());
		// Check if the bucket already exists.
		boolean isExist = minioClient.bucketExists(videoFolder);
		if (!isExist) {
			// Make a new bucket called asiatrip to hold a zip file of photos.
			minioClient.makeBucket(videoFolder);
		}
		// 上传文件 文件名使用uuid 保证文件唯一存在
		minioClient.putObject(videoFolder, uuid, is, contentType);
	}

}
